package org.darcy.service.business.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

import org.darcy.dao.business.BusinessContractMapper;
import org.darcy.entity.CheckCollect;
import org.darcy.entity.CheckDelivery;
import org.darcy.entity.CheckLibAnalysis;
import org.darcy.entity.business.BusinessContract;
import org.darcy.entity.business.BusinessFinancialBill;
import org.darcy.entity.business.BusinessFinancialReceived;
import org.darcy.entity.work.WorkInstance;
import org.darcy.framework.constant.BusinessType;
import org.darcy.framework.constant.SysConstant;
import org.darcy.framework.generic.GenericServiceImpl;
import org.darcy.framework.model.PageData;
import org.darcy.framework.model.PageParam;
import org.darcy.service.business.BusinessClientService;
import org.darcy.service.business.BusinessContractService;
import org.darcy.service.business.BusinessFinancialBillService;
import org.darcy.service.business.BusinessFinancialReceivedService;
import org.darcy.service.check.CheckCollectService;
import org.darcy.service.check.CheckDeliveryService;
import org.darcy.service.check.CheckLibAnalysisService;
import org.darcy.service.org.CompanyService;
import org.darcy.service.privilege.SysUserService;
import org.darcy.service.sys.SysFileService;
import org.darcy.service.work.WorkService;
import org.darcy.vo.ContractAmount;
import org.darcy.vo.project.FlowInfo;
import org.darcy.vo.project.ProjectList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;

/**
 * BusinessContract服务实现
 */
@Service
@Transactional
public class BusinessContractServiceImpl extends GenericServiceImpl<BusinessContract>
		implements BusinessContractService {

	@Autowired
	private BusinessContractMapper mapper;

	@Autowired
	@Lazy
	private BusinessFinancialReceivedService BusinessFinancialReceivedService;

	@Autowired
	@Lazy
	private SysFileService SysFileService;

	@Autowired
	@Lazy
	private BusinessFinancialBillService BusinessFinancialBillService;

	@Autowired
	@Lazy
	private CheckDeliveryService CheckDeliveryService;

	@Autowired
	@Lazy
	private CheckCollectService CheckCollectService;

	@Autowired
	@Lazy
	private CheckLibAnalysisService CheckLibAnalysisService;

	@Autowired
	private WorkService WorkService;

	@Autowired
	@Lazy
	private BusinessClientService BusinessClientService;

	@Autowired
	private SysUserService SysUserService;
	
	@Autowired
	private CompanyService CompanyService;

	/**
	 * 处理前端数据
	 */
	private void processData(BusinessContract record) {
		// 合同编号处理
		String time = null;
		Date createTime = null;
		boolean needChange = true; // 编号是否需要改变
		if (record.getId() != null) {
			BusinessContract existData = this.getById(record.getId());
			createTime = existData.getCreateTime();
			if (existData.getCompanyId().equals(record.getCompanyId())
					&& existData.getProjectType().equals(record.getProjectType())) {
				needChange = false;
			}
		} else {
			createTime = new Date();
		}
		if (needChange) {
			time = DateUtil.format(createTime, DatePattern.PURE_DATETIME_FORMATTER);
			String projecType = record.getProjectType().split(",")[0];// 取第一个项目类型
			switch (record.getCompanyId()) {
			case 101:
				if (projecType.equals("职业卫生")) {
					record.setFormNo("ZY" + time);
				} else {
					record.setFormNo("HJJC" + time);
				}
				break;
			case 102:
				if (projecType.equals("安全托管")) {
					record.setFormNo("FATG" + time);
				} else if (projecType.equals("标准化")) {
					record.setFormNo("FABZH" + time);
				} else {
					record.setFormNo("FAZX" + time);
				}
				break;
			case 103:
				if (projecType.equals("安全托管")) {
					record.setFormNo("ZHTG" + time);
				} else if (projecType.equals("标准化")) {
					record.setFormNo("ZHBZH" + time);
				} else if (projecType.equals("环保管家")) {
					record.setFormNo("ZHHBGJ" + time);
				} else {
					record.setFormNo("ZHZX" + time);
				}
				break;
			default:
				record.setFormNo("HT" + time);
				break;
			}
		}

		// 线上合同
		if (record.getOnlineContractList() != null && !record.getOnlineContractList().isEmpty()) {
			String file = SysFileService.getFileIdList(record.getOnlineContractList());
			record.setOnlineContract(Integer.parseInt(file));
		}
		// 处理附件
		if (record.getFileList() != null && !record.getFileList().isEmpty()) {
			String file = SysFileService.getFileIdList(record.getFileList());
			record.setFile(file);
		}
	}

	private void processWork(BusinessContract record) {
		BusinessContract data = this.getDetail(record.getId());
		String title = String.format("[%s]的合同登记", data.getProjectOperatorName());
		String summary = String.format("委托单位：%s\n委托业务：%s\n经办人：%s", data.getClientName(), data.getProjectType(),
				data.getProjectOperatorName());
		WorkService.addWorkTask(record, title, summary, SysConstant.FormType.BusinessContract);
	}

	private void processWorkConfirm(BusinessContract record) {
		BusinessContract data = this.getDetail(record.getId());
		String title = String.format("[%s]的合同确认", data.getProjectOperatorName());
		String summary = String.format("委托单位：%s\n委托业务：%s\n经办人：%s", data.getClientName(), data.getProjectType(),
				data.getProjectOperatorName());
		WorkService.addWorkTask(record, title, summary, SysConstant.FormType.ContractConfirm);
	}

	@Override
	public BusinessContract insert(BusinessContract record) {
		record.setCreateTime(new Date());
		processData(record);
		super.insert(record);
		processWork(record);
		return record;
	}

	@Override
	public BusinessContract updateFlow(BusinessContract record) {
		processData(record);
		super.update(record);
		processWork(record);
		return record;
	}

	@Override
	public BusinessContract updateConfirm(BusinessContract record) {
		// 合同确认：正式合同
		if (record.getConfirmFileList() != null && !record.getConfirmFileList().isEmpty()) {
			String file = SysFileService.getFileIdList(record.getConfirmFileList());
			record.setFormalFile(file);
		}
		super.update(record);
		processWorkConfirm(record);
		return record;
	}

	@Override
	public int delete(Object id) {
		super.delete(id);
		WorkInstance param = WorkInstance.builder().formId((Integer) id).formType(SysConstant.FormType.BusinessContract)
				.build();
		WorkInstance work = WorkService.getBusinessWork(param);
		WorkService.delete(work.getId());
		return 1;
	}

	@Override
	public BusinessContract getProjectData(Integer id) {
		// 1.合同
		BusinessContract data = this.getDetail(id);
		// 2.合同收款
		List<BusinessFinancialReceived> receiveList = BusinessFinancialReceivedService.getList(id);
		data.setReceiveList(receiveList);
		Float total = 0f;
		data.setReceivedAmountList(new ArrayList<ContractAmount>());
		for (BusinessFinancialReceived a : receiveList) {
			if (a.getPayAmount() == null) {
				continue;
			}
			total += a.getPayAmount();
			// 处理收款金额
			List<ContractAmount> list = JSONUtil.parseArray(a.getPayDetail()).toList(ContractAmount.class);
			data.getReceivedAmountList().addAll(list);
		}
		data.setReceivedAmountTotal(total);

		// 3.开票
		List<BusinessFinancialBill> billList = BusinessFinancialBillService.getList(id);
		total = 0f;
		for (BusinessFinancialBill a : billList) {
			total += a.getReceiptAmount();
		}
		data.setBillList(billList);
		data.setBillAmountTotal(total);
		// 4.派工单
		List<CheckDelivery> deliveryList = CheckDeliveryService.getList(id);
		data.setDeliveryList(deliveryList);
		// 5.采样
		for (CheckDelivery a : deliveryList) {
			List<CheckCollect> collectList = CheckCollectService.getList(a.getId(), true);
			a.setCollectList(collectList);
		}
		// 6.实验分析
		for (CheckDelivery a : data.getDeliveryList()) {
			List<CheckCollect> collectList = a.getCollectList();
			for (CheckCollect b : collectList) {
				List<CheckLibAnalysis> libList = CheckLibAnalysisService.getList(b.getId());
				b.setLibAnalysisList(libList);
			}
		}
		// 7.流程信息
		data.setWorkList(WorkService.getFlowList(id));
		processFlowInfo(data);
		// ....
		return data;
	}

	/**
	 * 处理流程信息，确定当前所在节点
	 */
	private void processFlowInfo(BusinessContract record) {
		FlowInfo[] flowInfoList = new FlowInfo[11];
		// 初始化
		flowInfoList[0] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.BusinessContract));
		flowInfoList[1] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.ContractConfirm));
		flowInfoList[2] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.FinancialReceived));
		flowInfoList[3] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.CheckDelivery));
		flowInfoList[4] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.CheckCaiYang));
		flowInfoList[5] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.CheckShouYang));
		flowInfoList[6] = new FlowInfo("实验");
		flowInfoList[7] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.HandOver));
		flowInfoList[8] = new FlowInfo("结算");
		flowInfoList[9] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.Archive));
		flowInfoList[10] = new FlowInfo(BusinessType.getBusinessName(SysConstant.FormType.FinancialBill));

		List<WorkInstance> workList = record.getWorkList();
		FlowInfo info = null;
		int index = 0;
		for (WorkInstance a : workList) {
			String name = BusinessType.getBusinessName(a.getFormType());
			info = new FlowInfo(name, a.getOperatorName());
			if (a.getStatus() == 100) {
				info.setTime(a.getStopTime());
			}

			switch (a.getFormType()) {
			case SysConstant.FormType.BusinessContract:
				index = 0;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.ContractConfirm:
				index = 1;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.FinancialReceived:
				index = 2;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.FinancialBill:
				index = 10;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.CheckDelivery:
				index = 3;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.CheckChangDiao1:
				break;
			case SysConstant.FormType.CheckChangDiao2:
				break;
			case SysConstant.FormType.CheckCaiYang:
				index = 4;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.CheckCaiYangDept:
				break;
			case SysConstant.FormType.CheckShouYang:
				index = 5;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.LibDispatch:
				index = 6;
				info.setName("实验");
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.LibAnalysis:
				index = 6;
				info.setName("实验");
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.LibReport:
				index = 6;
				info.setName("实验");
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.CheckReport:
				break;
			case SysConstant.FormType.ShowPublic:
				break;
			case SysConstant.FormType.CheckService:
				break;
			case SysConstant.FormType.HandOver:
				index = 7;
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.CloseDept:
				index = 8;
				info.setName("结算");
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.CloseFinancial:
				index = 8;
				info.setName("结算");
				flowInfoList[index] = info;
				break;
			case SysConstant.FormType.Archive:
				index = 9;
				flowInfoList[index] = info;
				break;
			default:
				break;
			}

		}
		record.setIndex(index);
		record.setFlowInfoList(flowInfoList);

	}

	@Override
	public BusinessContract getDetail(Integer id) {
		BusinessContract record = mapper.selectById(id);
		String name1 = CompanyService.getById(record.getCompanyId()).getCname();
		record.setCompanyName(name1);
		String name2 = SysUserService.getById(record.getProjectOperator()).getRealName();
		record.setProjectOperatorName(name2);
		String name3 = BusinessClientService.getById(record.getClientId()).getName();
		record.setClientName(name3);
		List<String> projectTypeList = Arrays.asList(record.getProjectType().split(","));
		record.setProjectTypeList(projectTypeList);
		// 处理合同金额
		List<ContractAmount> list = JSONUtil.parseArray(record.getContractAmount()).toList(ContractAmount.class);
		record.setContractAmountList(list);
		Float total = 0f;
		for (ContractAmount a : list) {
			total += a.getValue();
		}
		record.setContractAmountTotal(total);
		// 线上合同
		if (record.getOnlineContract() != null) {
			record.setOnlineContractList(SysFileService.getFilePathList(String.valueOf(record.getOnlineContract())));
		}
		// 文件处理
		if (StrUtil.isNotEmpty(record.getFile())) {
			record.setFileList(SysFileService.getFilePathList(record.getFile()));
		}
		// 盖章合同
		if (StrUtil.isNotEmpty(record.getFormalFile())) {
			record.setConfirmFileList(SysFileService.getFilePathList(record.getFormalFile()));
		}

		return record;
	}

	@Override
	public PageData<BusinessContract> page(PageParam<ProjectList> param) {
		IPage<BusinessContract> queryPage = new Page<BusinessContract>(param.getQuery().getPageNum(),
				param.getQuery().getPageSize());
		IPage<BusinessContract> data = mapper.getPage(queryPage, param.getEntity());
		PageData<BusinessContract> pageData = new PageData<BusinessContract>(data, param);
		return pageData;
	}

	@Override
	public List<BusinessContract> getAll(String keyword) {
		QueryWrapper<BusinessContract> q = new QueryWrapper<BusinessContract>();
		if (!StrUtil.isEmptyIfStr(keyword)) {
			q.like("form_no", keyword);
		}
		return this.getList(q);
	}

}
